/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[CloneBySerialization.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package io.serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 使用序列化进行克隆
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class CloneBySerialization implements Cloneable, Serializable {

	private static final long serialVersionUID = -3316429726810362379L;

	/**
	 * 使用ByteArrayInputStream, ByteArrayOutputStream实现对象克隆
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
		Object clone = null;

		ByteArrayInputStream inputStream = null;
		ByteArrayOutputStream outputStream = null;

		ObjectInputStream objectInputStream = null;
		ObjectOutputStream objectOutputStream = null;

		try {
			// 克隆的实现
			outputStream = new ByteArrayOutputStream();
			objectOutputStream = new ObjectOutputStream(outputStream);
			objectOutputStream.writeObject(this);

			inputStream = new ByteArrayInputStream(outputStream.toByteArray());
			objectInputStream = new ObjectInputStream(inputStream);

			clone = objectInputStream.readObject();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			if (objectOutputStream != null) {
				try {
					objectOutputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (objectInputStream != null) {
				try {
					objectInputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return clone;
	}

	public static void main(String[] args) throws CloneNotSupportedException {
		Person person1 = new Person("Sean", 20, 'M');
		System.out.println(person1);
		System.out.println(person1.hashCode());

		Person person2 = (Person) person1.clone();
		System.out.println(person2);
		System.out.println(person2.hashCode());
	}
}

/**
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class Person extends CloneBySerialization {

	private static final long serialVersionUID = 573470527406224743L;

	private String name = null;
	private int age = 0;
	private char gender = 'F';

	public Person() {
		super();
	}

	public Person(String name, int age, char gender) {
		super();
		this.name = name;
		this.age = age;
		this.gender = gender;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public char getGender() {
		return gender;
	}

	public void setGender(char gender) {
		this.gender = gender;
	}

	@Override
	public String toString() {
		return this.getClass().getName() + " [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}
}
